/*
** base class of containers
** and different types of containers
*/

#ifndef _CONTAINERS_H_
#define _CONTAINERS_H_

#include <cassert>
#include <string>
#include <iostream>
#include <fstream>
#include <cmath>
#include <numeric>

#ifdef WIN32
#include <Windows.h>
#endif
#include <GL/GL.h>

#include "error_info.h"
#include "polytope.h"

namespace Nesting
{
	/* 
	** container interface 
	*/
	class Container_box 
	{

	public:

		/*
		** query
		*/
		// unsigned volume
		virtual double volume() const = 0;
		virtual double x_min() const = 0;
		virtual double y_min() const = 0;
		virtual double x_max() const = 0;
		virtual double y_max() const = 0;
		virtual double z_min() const = 0;
		virtual double z_max() const = 0;

		/* 
		** contract or enlarge a container  
		** bottom remains fixed. top moves
		*/
		virtual void shrink(double factor) = 0;
		virtual void enlarge(double facotr) = 0;
		virtual void lower(double dh) = 0;

		// check whether a polytope is inside a box 
		virtual bool bounded_side(const Nesting_polytope& polytope) const = 0; 

		virtual void gl_draw() const = 0;

		virtual ~Container_box() {} ;
	};


	/* 
	** rectangluar container in 2-dimension 
	*/
	class Rectangular_box : public Container_box 
	{

	public:

		Rectangular_box(double x_min, double y_min, double x_max, double y_max);

		// read from file with format .line
		Rectangular_box(const std::string& line_fm_filename); 

		double volume() const;
		
		void shrink(double factor = 1.0) ;
		void enlarge(double factor = 1.0) ;
		void lower(double dh = 0.0) { max_y -= dh; }

		bool bounded_side(const Nesting_polytope& polytope) const;

		void gl_draw() const;

		// query
		double x_min() const { return min_x; }
		double y_min() const { return min_y; }
		double x_max() const { return max_x; }
		double y_max() const { return max_y; }
		double z_min() const { return 0.0; }
		double z_max() const { return 0.0; }

		~Rectangular_box() {}

	private:
		double min_x;
		double min_y;
		double max_x;
		double max_y;
	};
}

#endif